// *********************************************************************************
// Project Name : zkx2024
// Author       : Jlan
// Email        : 15533610762@163.com
// Create Time  : 2024-04-11
// File Name    : testbench.v
// Module Name  :
// Called By    :jlan
// Abstract     :
//
// 
// *********************************************************************************
// Modification History:
// Date         By              Version                 Change Description
// -----------------------------------------------------------------------
// 2024-04-11    Macro           1.0                     Original
//  
// *********************************************************************************

`timescale 1ns/1ps 
module testbench ;
logic   [0:0]               CLK;
logic   [0:0]               RST_N;
logic   [0:0]               WR_EN;
logic   [3:0]               WR_DATA;
logic   [0:0]               RD_EN;
logic   [3:0]               RD_DATA;
logic   [0:0]               FULL;
logic   [0:0]               EMPTY;
logic   [0:0]               CLEAR;

st_fifo_bus#(.FIFO_WIDTH(16)) itfc(.*);
//inst_dut
fifo_ctrl#(.FIFO_WIDTH(16),
           .FIFO_DEPTH(16))
           dut(itfc.fifo);
//sync_fifo#(.FIFO_WIDTH(4),
//           .FIFO_DIPTH(4))
//           dut(.*);

//clk rst_n

initial begin
    CLK =   '0;
    RST_N = 1'b1;
    CLEAR = '0;
end

always #5 CLK = ~CLK;

//write task
task  write(input int sed);
//rand  logic  [3:0]   wr_data;
logic  [3:0]   wr_data;
logic           full;
       @(posedge CLK);#1;
       //assert(wr_data.randomize());
       wr_data = sed;
       WR_EN = 1;
       WR_DATA = wr_data;
       full=FULL;
       @(posedge CLK);#1;
       WR_EN = '0;
       if((!dut.FULL)&&(dut.fifo_mem[dut.wr_addr[1:0]-1]!=wr_data))begin
           $display("@:%0t:fifo_write error!!!",$time);$finish;
       end
       else if((!full)&&(dut.wr_addr[1:0]==0)&&(dut.fifo_mem[3]==wr_data))
           $display("@:%0t:fifo write normal!!!",$time);
       else if((!full)&&(dut.fifo_mem[dut.wr_addr[1:0]-1]==wr_data))
           $display("@:%0t:fifo write normal!!!",$time);
       else if(dut.FULL)
           $display("@:%0t:fifo full !!!",$time);
//       else
//           $display("@:%0t:fifo write normal!!!",$time);

endtask
task  read();
int rd_data;
logic empty;
    @(posedge CLK);#1;
    RD_EN   =   1;
    empty=EMPTY;
    @(posedge CLK);#1;
    RD_EN = '0;
    rd_data = RD_DATA;
    if((!dut.EMPTY)&&(dut.fifo_mem[dut.rd_addr[1:0]-1]!=rd_data))begin
           $display("@:%0t:fifo_read error!!!",$time);$finish;
       end
       else if((!empty)&&(dut.rd_addr[1:0]==0)&&(dut.fifo_mem[3]==rd_data))
           $display("@:%0t:fifo read normal!!!",$time);
       else if((!empty)&&(dut.fifo_mem[dut.rd_addr[1:0]-1]==rd_data))
           $display("@:%0t:fifo read normal!!!",$time);
       else if(dut.EMPTY)
           $display("@:%0t:fifo EMPTY !!!",$time);
//       else
//           $display("@:%0t:fifo read normal!!!",$time);

endtask

initial begin
    repeat(5)@(posedge CLK);#1;
    RST_N   = '0;
    repeat(5)@(posedge CLK);#1;
    RST_N   = 1'b1;
    for(int i=0;i<10;i++)begin
        write(i);
    end
    for(int J=0;J<10;J++)begin
        read();
    end
    for(int i=0;i<10;i++)begin
        write(i);
        read();
    end
    write(10);
    write(10);
    write(10);
    write(10);
    write(10);
    write(10);
    CLEAR = 1'b1;
    #100;$finish;
end

//----------------------------------
//gen fsdb
//----------------------------------

initial	begin
	    $fsdbDumpfile("tb.fsdb");	    
        $fsdbDumpvars;
        $fsdbDumpMDA();
end

endmodule
